"""
数据预处理脚本 - 修复版本
支持中文列名的CSV文件处理
"""

import pandas as pd
import json
import re
import os
from datetime import datetime

class DataPreprocessor:
    """数据预处理器"""
    
    def __init__(self):
        self.output_format = {
            "product_name": "",
            "price": 0,
            "specs": {},
            "comments": []
        }
    
    def load_raw_data(self, file_path):
        """
        加载原始数据
        支持CSV, JSON, Excel格式
        """
        file_ext = os.path.splitext(file_path)[1].lower()
        
        try:
            if file_ext == '.csv':
                # 尝试不同的编码格式
                for encoding in ['utf-8', 'utf-8-sig', 'gbk', 'gb2312']:
                    try:
                        df = pd.read_csv(file_path, encoding=encoding)
                        print(f"✓ 成功使用 {encoding} 编码读取文件")
                        print(f"✓ 检测到列名: {list(df.columns)}")
                        print(f"✓ 数据行数: {len(df)}")
                        return df
                    except UnicodeDecodeError:
                        continue
                raise ValueError("无法使用常见编码读取CSV文件")
            elif file_ext == '.json':
                with open(file_path, 'r', encoding='utf-8') as f:
                    return json.load(f)
            elif file_ext in ['.xlsx', '.xls']:
                return pd.read_excel(file_path)
            else:
                raise ValueError(f"不支持的文件格式: {file_ext}")
        except Exception as e:
            print(f"读取文件失败: {e}")
            return None
    
    def clean_comment_text(self, text):
        """清洗评论文本"""
        if pd.isna(text) or not isinstance(text, str):
            return ""
        
        # 去除HTML标签
        text = re.sub(r'<[^>]+>', '', text)
        
        # 去除特殊字符和多余空格
        text = re.sub(r'[^\u4e00-\u9fff\w\s\.,!?，。！？]', '', text)
        text = re.sub(r'\s+', ' ', text).strip()
        
        # 过滤过短的评论
        if len(text) < 3:
            return ""
        
        return text
    
    def standardize_date(self, date_str):
        """标准化日期格式"""
        if pd.isna(date_str) or not date_str:
            return ""
        
        # 处理字符串格式的日期
        date_str = str(date_str).strip()
        
        # 尝试多种日期格式
        date_formats = [
            "%Y/%m/%d %H:%M",
            "%Y-%m-%d %H:%M",
            "%Y/%m/%d",
            "%Y-%m-%d",
            "%Y/%m/%d %H:%M:%S",
            "%Y-%m-%d %H:%M:%S"
        ]
        
        for fmt in date_formats:
            try:
                date_obj = datetime.strptime(date_str, fmt)
                return date_obj.strftime("%Y-%m-%d")
            except:
                continue
        
        print(f"⚠️ 无法解析日期格式: {date_str}")
        return ""
    
    def safe_get_rating(self, rating_value):
        """安全获取评分值"""
        if pd.isna(rating_value):
            return 3
        
        try:
            # 如果是数字，直接转换
            rating = float(rating_value)
            # 确保评分在1-5之间
            rating = max(1, min(5, int(rating)))
            return rating
        except:
            print(f"⚠️ 无法解析评分: {rating_value}")
            return 3
    
    def process_comments(self, raw_data, product_name):
        """
        处理评论数据 - 支持中文列名
        
        Args:
            raw_data: 原始数据 (DataFrame 或 dict)
            product_name: 产品名称
        
        Returns:
            dict: 标准化的产品数据
        """
        processed_data = {
            "product_name": product_name,
            "price": 0,
            "specs": {},
            "comments": []
        }
        
        if isinstance(raw_data, pd.DataFrame):
            print(f"📊 开始处理DataFrame，共 {len(raw_data)} 行数据")
            
            # 获取列名
            columns = raw_data.columns.tolist()
            print(f"📋 CSV列名: {columns}")
            
            # 检查必要的列是否存在
            required_columns = ['评论', '评分']
            missing_columns = [col for col in required_columns if col not in columns]
            if missing_columns:
                print(f"❌ 缺少必要的列: {missing_columns}")
                print(f"💡 请确保CSV文件包含以下列名: {required_columns}")
                return processed_data
            
            valid_comments = 0
            
            # 处理DataFrame格式 - 使用中文列名
            for index, row in raw_data.iterrows():
                try:
                    # 使用中文列名获取数据
                    comment_text = self.clean_comment_text(row['评论'])
                    if comment_text:
                        comment_data = {
                            "content": comment_text,
                            "rating": self.safe_get_rating(row['评分']),
                            "date": self.standardize_date(row.get('日期', '')),
                            "length": len(comment_text),
                            "user_id": str(row.get('昵称', f"user_{index}")) if pd.notna(row.get('昵称')) else f"user_{index}"
                        }
                        processed_data["comments"].append(comment_data)
                        valid_comments += 1
                        
                        # 打印前几条评论作为样本
                        if valid_comments <= 3:
                            print(f"📝 样本评论 {valid_comments}: {comment_text[:30]}...")
                            
                except Exception as e:
                    print(f"⚠️ 处理第 {index+1} 行数据时出错: {e}")
                    continue
            
            print(f"✓ 成功处理 {valid_comments} 条有效评论")
            
            # 如果存在产品列，提取产品信息
            if '产品' in raw_data.columns:
                try:
                    product_info = raw_data['产品'].iloc[0]
                    if pd.notna(product_info):
                        processed_data["product_name"] = str(product_info)
                        processed_data["specs"]["original_product_name"] = str(product_info)
                except:
                    pass
            
            # 提取价格信息（如果存在）
            if '价格' in raw_data.columns:
                try:
                    price_value = raw_data['价格'].iloc[0]
                    if pd.notna(price_value):
                        processed_data["price"] = float(price_value)
                except:
                    pass
        
        elif isinstance(raw_data, dict):
            # 处理字典格式（保持原有逻辑）
            processed_data["price"] = raw_data.get("price", 0)
            processed_data["specs"] = raw_data.get("specs", {})
            
            for comment in raw_data.get("comments", []):
                comment_text = self.clean_comment_text(comment.get('content', ''))
                if comment_text:
                    comment_data = {
                        "content": comment_text,
                        "rating": self.safe_get_rating(comment.get('rating', 3)),
                        "date": self.standardize_date(comment.get('date', '')),
                        "length": len(comment_text),
                        "user_id": str(comment.get('user_id', ''))
                    }
                    processed_data["comments"].append(comment_data)
        
        return processed_data
    
    def save_processed_data(self, processed_data, output_path):
        """保存处理后的数据"""
        # 确保输出目录存在
        os.makedirs(os.path.dirname(output_path), exist_ok=True)
        
        with open(output_path, 'w', encoding='utf-8') as f:
            json.dump(processed_data, f, ensure_ascii=False, indent=2)
        
        print(f"✓ 已保存到: {output_path}")
        print(f"  产品: {processed_data['product_name']}")
        print(f"  评论数量: {len(processed_data['comments'])}")
        
        # 显示样本数据
        if processed_data['comments']:
            print(f"  样本评论: {processed_data['comments'][0]['content'][:50]}...")
            print(f"  平均评分: {sum(c['rating'] for c in processed_data['comments']) / len(processed_data['comments']):.1f}")

def main():
    """主处理流程"""
    preprocessor = DataPreprocessor()
    
    # 配置输入输出路径
    input_dir = "data/raw"
    output_dir = "data/processed"
    
    # 确保输出目录存在
    os.makedirs(output_dir, exist_ok=True)
    
    if not os.path.exists(input_dir):
        print(f"❌ 输入目录不存在: {input_dir}")
        print(f"💡 请创建目录并放入CSV文件: {input_dir}")
        return
    
    # 获取输入目录中的文件
    files = [f for f in os.listdir(input_dir) if f.endswith(('.csv', '.json', '.xlsx', '.xls'))]
    
    if not files:
        print(f"❌ 在 {input_dir} 目录中未找到支持的文件格式")
        print(f"💡 支持的格式: .csv, .json, .xlsx, .xls")
        return
    
    print(f"🔍 找到 {len(files)} 个文件: {files}")
    
    # 处理所有原始数据文件
    processed_count = 0
    for filename in files:
        print(f"\n{'='*60}")
        print(f"📁 处理文件: {filename}")
        print(f"{'='*60}")
        
        input_path = os.path.join(input_dir, filename)
        product_name = os.path.splitext(filename)[0]
        
        # 加载原始数据
        raw_data = preprocessor.load_raw_data(input_path)
        if raw_data is None:
            print(f"❌ 跳过文件: {filename}")
            continue
        
        # 处理数据
        processed_data = preprocessor.process_comments(raw_data, product_name)
        
        if not processed_data['comments']:
            print(f"⚠️ 未能提取到有效评论数据，请检查:")
            print(f"   1. CSV文件是否包含'评论'和'评分'列")
            print(f"   2. 评论内容是否为空")
            print(f"   3. 文件编码是否正确")
            continue
        
        # 保存处理后的数据
        output_path = os.path.join(output_dir, f"{product_name}_processed.json")
        preprocessor.save_processed_data(processed_data, output_path)
        processed_count += 1
    
    print(f"\n🎉 处理完成!")
    print(f"📊 总文件数: {len(files)}")
    print(f"✅ 成功处理: {processed_count}")
    print(f"❌ 失败文件: {len(files) - processed_count}")

if __name__ == "__main__":
    main()